package com.smh;

import com.smh.interfaces.Queue;
import org.junit.jupiter.api.Test;

import java.util.Iterator;

import static org.junit.jupiter.api.Assertions.assertNull;

/**
 * @author shiminghui
 * @date 2025/2/9 20:44
 * @description: TODO
 */
public class _013_队列_链表 {
    @Test
    public void test1() {
        Queue<Integer> queue = new MyQueue<Integer>(1);
        queue.offer(1);
        queue.offer(2);
        Integer poll = queue.poll();
        System.out.println(poll);
        Integer poll1 = queue.poll();
        System.out.println(poll1);
        Integer poll2 = queue.poll();
        System.out.println(poll2);
        Integer peek = queue.peek();
        assertNull(peek);
        System.out.println(peek);

    }

    public static class MyQueue<T> implements Queue<T>, Iterable<T> {

        private ListNode<T> head = new ListNode<T>();
        private ListNode<T> tail = head;

        private int size; // 队列长度
        private int capacity; // 队列容量

        {
            head.next = head;
        }

        public MyQueue() {
            capacity = 10;
        }

        public MyQueue(int capacity) {
            this.capacity = capacity;
        }

        @Override
        public boolean offer(T value) {
            if (isFull()) {
                return false;
            }
            ListNode<T> newNode = new ListNode<T>(value);
            newNode.next = tail.next;
            tail.next = newNode;
            tail = newNode;
            size++;
            return true;
        }

        @Override
        public T poll() {
            if (isEmpty()) {
                return null;
            }
            T value = head.next.value;
            if (head.next == tail) {
                tail = head;
            }
            head.next = head.next.next;
            size--;
            return value;
        }

        @Override
        public T peek() {
            if (isEmpty()) {
                return null;
            }
            return head.next.value;
        }

        @Override
        public boolean isEmpty() {
            if (size == 0) {
                return true;
            }
            return false;
        }

        @Override
        public boolean isFull() {
            if (size >= capacity) {
                return true;
            }
            return false;
        }

        @Override
        public Iterator<T> iterator() {
            return new Iterator<T>() {

                ListNode<T> p = head.next;

                @Override
                public boolean hasNext() {
                    if (p.next == head) {
                        return false;
                    }
                    return true;
                }

                @Override
                public T next() {
                    T value = p.value;
                    p = p.next;
                    return value;
                }
            };
        }


        private static class ListNode<T> {
            private T value;
            private ListNode<T> next;

            public ListNode(T value) {
                this.value = value;
            }

            public ListNode() {
            }

            public ListNode(T value, ListNode<T> next) {
                this.value = value;
                this.next = next;
            }

        }
    }


}